package io.zpy.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.zpy.config.Utils;
import io.zpy.dao.TrackTopicsDao;
import io.zpy.entity.PushOrder;
import io.zpy.entity.SendRecord;
import io.zpy.quartz.QuartzManager;
import io.zpy.quartz.ScheduleJob;
import io.zpy.service.TrackTopicsService;
import io.zpy.utils.FastJsonUtils;
import io.zpy.utils.R;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 *
 * @author wuyifan
 * @date 2020/5/13
 */
@Service
public class TrackTopicsServiceImpl implements TrackTopicsService {

    @javax.annotation.Resource
    private TrackTopicsDao trackTopicsDao;

    @Autowired
    private QuartzManager quartzManager;

    @Value("classpath:json/test.json")
    private Resource domian;

    @Override
    public JSONObject getOwnPushOrders(String uid) {
        String result = "";
        JSONObject json = new JSONObject();
        try {
            //查询订单
            List<PushOrder> list = trackTopicsDao.getOwnPushOrders(uid, "");
//          分页
            int pageNum = 0;
            int pageSize = 10;//这两个是参数 传进来的
            PageHelper.startPage(pageNum, pageSize);
            PageInfo<PushOrder> pageInfo = new PageInfo<PushOrder>(list);

            String data = FastJsonUtils.toJSONString(pageInfo);
            JSONObject object = Utils.formatJson(JSON.parseObject(data));

            json.put("orders", object.get("list"));
            return json;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = {Throwable.class})
    public String quartzJob(ScheduleJob sj) {
        String result = "";
        try {
            result = IOUtils.toString(domian.getInputStream(), Charset.forName("UTF-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        //(2)返回结果组装
        String str = Utils.jsonToString(result);
        //处理邮件content成html文件
//        String html = "<html><head><meta http-equiv='content-type' content='text/html;charset=gbk'>";
//        html += "<meta http-equiv='refresh' content='1'></head><body style='color: Red'><p>今日推送文章:</p>";
//        html += str;
//        html += "</body></html>";
        String html = "<html><head><meta http-equiv='content-type' content='text/html;charset=gbk'>\n" +
                "<meta http-equiv='refresh' content='1'></head><body>\n" +
                "    <h3 style='color: Red'> " + str + "</h3>\n" +
                "</body>\n" +
                "</html>";
        //
        //(3)调取发送邮件接口
        //此处省略，返回发送邮件结果code和msg
        try {
            SendRecord sr = new SendRecord();
            sr.setToAddress(sj.getToAddress());
            sr.setDetail(str);
            sr.setAmount(str.split("；").length);
            sr.setFrequency(sj.getFrequency());
            sr.setTrackAmount(sj.getTrackAmount());
            sr.setCode(200);
            sr.setMsg("成功");
            sr.setSendDate(Utils.getDateFormat());
            sr.setJobName(sj.getJobName());
            sr.setJobGroup(sj.getJobGroup());
            sr.setCronExpression(sj.getCronExpression());
            sr.setPid(sj.getPid());
            sr.setUid(sj.getUid());
            int count = trackTopicsDao.insertSendRecord(sr);

            List<SendRecord> list = trackTopicsDao.getCountSucOrders(sj.getJobName(), sj.getPid());
            if (list.size() > 0) {
                int suc = 0;
                int fail = 0;
                for (SendRecord s : list) {
                    if (s.getCode() == 200) {
                        suc++;
                    } else {
                        fail++;
                    }
                }

                //当同一个订单定时任务触发3次及以上，邮件发送记录仍全部失败，则剔除该定时任务并且将订单表定时器相关字段重置为空
                //或者当一个定时器为一次性的 如果有一次成功发送记录则也移除定时器并置空
                if ((suc == 0 && fail >= 3) || (suc > 0 && sj.getFrequency().equals("3"))) {
                    quartzManager.deleteJob(sj);
                    //同时置空订单表中的job信息
                    trackTopicsDao.updatePoJobInfo("", "", "", sj.getPid(), sj.getJobName());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        }

        return "success";
    }


    @Override
    public List<PushOrder> getPushOrderByPid(String uid, String pid) {
        return trackTopicsDao.getOwnPushOrders(uid, pid);
    }

    @Override
    public int editPushOrder(PushOrder po) throws Exception {
        R r = null;
        int count = 0;
        //编辑前先查询出原订单信息的追踪频率和追踪数量，如果更新操作这两个字段未变化，就不用动定时器
        List<PushOrder> list = trackTopicsDao.getOwnPushOrders("", String.valueOf(po.getPid()));
        PushOrder p = list.get(0);

        count = trackTopicsDao.editPushOrder(po);

        if (count > 0 && ((!(p.getFrequency().equals(po.getFrequency()) && p.getTrackAmount().equals(po.getTrackAmount()))) || (p.getJobName().equals("") && p.getJobGroup().equals("")))) {
            po.setJobName(p.getJobName());
            po.setJobGroup(p.getJobGroup());
            po.setCreateDate(p.getCreateDate());
            ScheduleJob job = Utils.initScheduleJob(po, "2");
            PushOrder poi = new PushOrder();
            poi.setCronExpression(job.getCronExpression());
            poi.setPid(po.getPid());
            poi.setUid(po.getUid());
            // 任务名称
            String jobName = UUID.randomUUID().toString();
            // 任务所属分组
            String jobGroup = ScheduleJob.class.getName();
            if (!(p.getJobName().equals("") && p.getJobGroup().equals(""))) {
                quartzManager.deleteJob(job);
            }
            job.setJobName(jobName);
            job.setJobGroup(jobGroup);
            quartzManager.addJob(job);
//                boolean flag = quartzManager.updateJobCron(job, jobName, jobGroup);
            poi.setJobName(jobName);
            poi.setJobGroup(jobGroup);
            trackTopicsDao.editPushOrder(poi);

        }
        return count;
    }

    @Override
    public int delPushOrder(Integer pid) throws Exception {
        R r = null;
        int count = 0;
        //删除订单记录前取出job信息，需操作对应定时任务
        List<PushOrder> list = trackTopicsDao.getOwnPushOrders("", String.valueOf(pid));
        PushOrder p = list.get(0);

        count = trackTopicsDao.delPushOrder(pid);
        if (count > 0) {
            ScheduleJob sj = new ScheduleJob();
            sj.setJobName(p.getJobName());
            sj.setJobGroup(p.getJobGroup());
            quartzManager.deleteJob(sj);
        }
        return count;
    }

    @Override
    public int addPushOrder(PushOrder po) throws Exception {
        R r = null;
        int count = 0;
        Integer pid = 0;
        // 任务名称
        String jobName = UUID.randomUUID().toString();
        // 任务所属分组
        String jobGroup = ScheduleJob.class.getName();
        po.setJobName(jobName);
        po.setJobGroup(jobGroup);
        ScheduleJob job = Utils.initScheduleJob(po, "1");
        po.setCronExpression(job.getCronExpression());
        //在一开始就插入表达式，任务名称等字段是存在一个问题，如果订单生成，定时器还未触发更新订单表这些信息时，服务停止或重启，则之前订单
        //的job信息会丢失
        count = trackTopicsDao.addPushOrder(po);
        //添加订单成功，准备进入定时器初始化
        if (count > 0) {
            pid = po.getPid();
            job.setPid(pid);
            quartzManager.addJob(job);
        }
        return count;
    }

    @Override
    public void runAllJobs() throws Exception {

        List<PushOrder> list = trackTopicsDao.getAllJobs();
        System.out.println("<<<<<<<<<<<<<<" + "定时器初始化开始" + ">>>>>>>>>>>>>>>");
        list.forEach(i->{
            System.out.println(i);
        });
        for (PushOrder po : list) {
            ScheduleJob job = new ScheduleJob();
            job = Utils.initScheduleJob(po, "3");
            quartzManager.addJob(job);
        }
        System.out.println("<<<<<<<<<<<<<<" + "定时器初始化结束" + ">>>>>>>>>>>>>>>");

    }
    @Override
    @Transactional(rollbackFor = {Throwable.class})
    public void quartzJobTest(ScheduleJob sj) {
        SendRecord sr = new SendRecord();
        sr.setToAddress(sj.getToAddress());
        sr.setFrequency(sj.getFrequency());
        sr.setTrackAmount(sj.getTrackAmount());
        sr.setCode(200);
        sr.setMsg("成功");
        sr.setSendDate(Utils.getDateFormat());
        sr.setJobName(sj.getJobName());
        sr.setJobGroup(sj.getJobGroup());
        sr.setCronExpression(sj.getCronExpression());
        sr.setPid(sj.getPid());
        sr.setUid(sj.getUid());
        System.out.println("任务："+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(new Date())+"：：：pid:"+sr.getPid()+"name:"+sr.getJobName()+"***"+sr.getCronExpression());
    }
}
